﻿//===============================================================================
//	Player.h
//	用户类
//===============================================================================

#pragma once

#include <string>
#include <stdint.h>
#include "../../3rd/libjson/json.h"

#include "UIntArray.h"

#include "TempValue.h"

#include <mutex>

#include "../share/object.h"
#include "entity.h"
#include "UpdatePlayerBroadcast.h"
#include "entity.h"
#include "PlayerDataStruct.h"
#include "CZeroBlood.h"

class BaseMessage;

class CUpdatePlayerInfo;
class CGeneralJsonStringRet;
class LuaManager;


class CKick;
class CPing;
class CEnterScene;
class CLeaveScene;

class CPlayerLoadSceneFinished;
class CPlayerMove;

class GDGeneralMessage;

class PlayerCommon;	//	用户通用属性
class PlayerVision;


class CLoginMapSrvRet;



/************************************
 *	玩家获得称号类型定义
 *	! 该类型对应称号脚本id，不可更改*/
enum e_title_type_name
{
	title_refill = 20000,
	title_total = 20001,
	title_level = 20002,
	title_moba_rank = 20003,
	title_level_rank = 20004,
	title_fc_rank = 20005,
};

enum class PlayerState : int32_t
{
	ps_pre_enter_scene,
	ps_in_scene,
	ps_normal,
	ps_dead,
};

static const uint32_t player_key_start = 4200000000;//	uint32最大4294967295

class Player: public CEntity
{
	static const uint32_t size_1024 = 1024;
	static const uint32_t title_state_size = 32;
	static const uint32_t title_state_start = 512;	//索引位置 = id + idx
	static const uint32_t title_state_end = title_state_start + title_state_size;
	static const uint32_t max_property_count = 17;	//最大属性条目数量
	static const uint32_t max_hero_count = 120;		// 最大英雄个数

private:
	uint32_t							m_PlayerId;
	uint32_t							m_socket_id;			//	socket ID

	// --
	char								m_Name[32];				// 昵称
	char								m_UnionName[64];		// 工会名称

	uint32_t							m_Account;				// 帐号
	uint32_t							m_Area;					// 所在游戏区
	uint32_t							m_Photo;				// 头像ID
	uint32_t							m_PhotoFrame;			// 头像框ID
	uint32_t							m_Exps;					// 当前经验值
	uint32_t							m_MaxExps;				// 当前最大经验值
	uint32_t							m_Level;				// 当前等级
	uint32_t							m_HeroId;				// 当前英雄ID
	uint32_t							m_HeroSkinId;			// 当前英雄皮肤ID
	uint32_t							m_Vip;					// VIP等级
	uint32_t							m_VipExps;				// VIP经验
	uint32_t							m_UnionId;				// 工会ID
	uint32_t							m_UnionPosition;		// 工会职位
	uint32_t							m_Afc;					// 战队战斗力

	

	uint32_t							m_PetId;				// 出战宠物ID
	uint32_t							m_MountsId;				// 骑乘坐骑ID
	uint32_t							m_MountState;			// 坐骑骑乘状态: 0: 未骑乘, 1:骑乘
	uint32_t							m_CurrHeroLevel;		// 当前出阵英雄等级
	uint32_t							m_DefPetId;				// 默认设定宠物ID
	uint32_t							m_DefMountsId;			// 默认设定坐骑ID
	PlayerState							m_player_state;
	uint32_t							m_hp;					// 玩家血量

private:
	CKick*								m_kick;
	CPing*								m_ping;
	CEnterScene*						m_enter_scene;
	CLeaveScene*						m_leave_scene;
	CPlayerLoadSceneFinished*			m_player_load_scene_finished;
	CLoginMapSrvRet*					m_login_mapsrv_ret;
	CZeroBlood*							m_target_zero_blood_notify;

private:
	UpdatePlayerBroadcast				m_update_player_broadcast;
	PlayerHero							m_playerHero[max_hero_count];
private:
	void createSocketMessage(void);
	void deleteSocketMessage(void);
	void clearPlayerInfo(void);
public:
	
	static const uint32_t name_str_len = 32;
	static const uint32_t fixed_part_pos_count = 16;

public:
	Player(void);
	~Player(void);

public:
	virtual void TickUpdate();
	virtual bool IsDeaded();
public:
	//---------------------------------------------------------------------------
	void Send2CEnterScene(uint32_t sceneId, int32_t ret_code = 0);
	void Send2CLevelScene(uint32_t sceneId);
	void sendPlayerLoadSceneFinished(void);

	void SendToClient(std::string* str, uint32_t msgId = 0);


	uint32_t GetSocketId(void);
	void SetSocketId(uint32_t socketId);

	void SetName(const char* v);
	char* GetName(void);

	void SetUnionName(const char* v);
	char* GetUnionName(void);

	void SetPingTime(uint32_t ch, uint32_t cl);
	bool CheckPingTime(void);

	uint32_t GetPlayerHp();
	bool SetCurrentHp(int32_t blood);

	UpdatePlayerBroadcast& GetUpdatePlayerBroadcast() {
		return m_update_player_broadcast;
	}

	access_variable(uint32_t,	Account,		m_Account);				// 帐号
	access_variable(uint32_t,	PlayerId,		m_PlayerId);			// 帐号
	access_variable(uint32_t,	Area,			m_Area);				// 所在游戏区
	access_variable(uint32_t,	Photo,			m_Photo);				// 头像ID
	access_variable(uint32_t,	PhotoFrame,		m_PhotoFrame);			// 头像框ID

	access_variable(uint32_t,	Exps,			m_Exps);				// 当前经验值
	access_variable(uint32_t,	MaxExps,		m_MaxExps);				// 当前最大经验值
	access_variable(uint32_t,	Level,			m_Level);				// 当前等级
	//access_variable(uint32_t,	HeroId,			m_HeroId);				// 当前英雄ID
	access_variable(uint32_t,	HeroSkinId,		m_HeroSkinId);			// 当前英雄皮肤ID
	access_variable(uint32_t,	Vip,			m_Vip);					// VIP等级
	access_variable(uint32_t,	VipExps,		m_VipExps);				// VIP经验
	access_variable(uint32_t,	UnionId,		m_UnionId);
	access_variable(uint32_t,	UnionPosition,	m_UnionPosition);
	access_variable(uint32_t,	Afc,			m_Afc);					// 战队战斗力


	access_variable(uint32_t,	PetId,			m_PetId);				// 宠物ID
	access_variable(uint32_t,	MountsId,		m_MountsId);			// 坐骑ID
	access_variable(uint32_t,	MountsState,	m_MountState);			//坐骑骑乘状态
	access_variable(uint32_t,	CurrHeroLevel,	m_CurrHeroLevel);		// 当前出阵英雄等级
	access_variable(uint32_t,	DefPetId,		m_DefPetId);
	access_variable(uint32_t,	DefMountsId,	m_DefMountsId);

	access_variable(PlayerState, PlayerState,	m_player_state);		

// 重新实现access_variable 的方法
	void SetHeroId(uint32_t hero_id);
	uint32_t GetHeroId() { return m_HeroId; }

public:
	//---------------------------------------------------------------------------
	//	转换场景
	void ChangeScene(int32_t flag, uint32_t to, uint32_t from = 0);

	//	前端加载场景完成
	void LoadSceneFinished(void);

	void SendPlayerLoginMapSrvResult(void);
	//---------------------------------------------------------------------------
	//	修改生命值
	void ModifyHp(uint32_t srcKey, uint32_t tarKey, int32_t val);
	//---------------------------------------------------------------------------
	//	广播死亡
	void BroadcastSomeoneDead(uint32_t sourceKey, uint32_t targetKey, uint32_t reviveCount);

	bool PlayerInGame();

	void KickPlayerNotify(uint32_t kickType);
	void KilledSomeone(CEntity* tar);
	void InitializePlayerSceneInfo(bool isReset);
	PlayerHero* GetPlayerHeroInfoByID(uint32_t heroId);
	HeroProperty * GetMainHeroProperty(void);
	void TargetZeroBloodNotify(uint32_t tarId);
	//void loadSceneFinished(void);
	PlayerHero* GetPlayerHeroEmptyPos();
	void SetOneHeroInfo(uint32_t heroId, Json::Value& jm);
	void ResetOneHeroInfo(uint32_t heroId, Json::Value& jm);
	void SendToGameUpdateHeroInfo(uint32_t heroid);
	void Revive(uint32_t srcKey, uint32_t tarKey, int32_t reviveType);
	void BroadcastRevive(uint32_t srcKey, uint32_t tarKey,
		int32_t reviveType, int32_t hp);
	void PlayerHeal(int32_t val);
	void SyncHeroGame2Map(uint32_t hero_id);

public:
	::common::CListLink< Player >& player_link() { return player_link_; }
	PlayerVision& vision_link() { return vision_link_; }

	virtual void SerialToJson(Json::Value& baseinfo);
	int32_t GetSceneId();

public:
	::common::CListLink< Player > player_link_;
	::common::CVector3 last_pos_;
	PlayerVision vision_link_;

private:
	int32_t last_ping_time_;
	
};
